// 文件名：map_symbol_table.cpp
// 目的：使用“栈 + 映射”的层级符号表，实现作用域的进入、离开、定义与查找。
// 模型：
//   - scopes_：栈顶为当前作用域，每层为 std::map（按标识符排序）；
//   - enterScope/leaveScope：作用域管理；
//   - define：在当前作用域定义符号；
//   - lookup：从内到外逐层查找（示例通过拷贝栈迭代，简洁但有额外开销）。
// 说明：
//   - 为演示简化，lookup/dump 通过复制栈进行遍历；实际可维护链式结构或显式迭代器以避免拷贝。
//   - 比较器使用 std::less<> 支持异构比较（与 string_view 等协同）。

#include <iostream>
#include <map>
#include <optional>
#include <stack>
#include <string>

class SymbolTable {
public:
    void enterScope() { scopes_.push({}); }
    void leaveScope() { if (!scopes_.empty()) scopes_.pop(); }

    void define(std::string name, int value) {
        scopes_.top().emplace(std::move(name), value);
    }

    std::optional<int> lookup(const std::string& name) const {
        auto copy = scopes_;
        while (!copy.empty()) {
            const auto& scope = copy.top();
            if (auto it = scope.find(name); it != scope.end()) {
                return it->second;
            }
            copy.pop();
        }
        return std::nullopt;
    }

    void dump() const {
        std::cout << "Scopes (inner to outer):\n";
        auto copy = scopes_;
        while (!copy.empty()) {
            for (const auto& [k, v] : copy.top()) {
                std::cout << "  " << k << " = " << v << '\n';
            }
            copy.pop();
            if (!copy.empty()) std::cout << "  ---\n";
        }
    }

private:
    std::stack<std::map<std::string, int, std::less<>>> scopes_;
};

int main() {
    SymbolTable table;
    table.enterScope();
    table.define("x", 1);
    table.define("y", 2);

    table.enterScope();
    table.define("x", 42);

    table.dump();

    if (auto value = table.lookup("x")) {
        std::cout << "lookup(x) -> " << *value << '\n';
    }
    table.leaveScope();
    if (auto value = table.lookup("x")) {
        std::cout << "lookup(x) after leaving inner scope -> " << *value << '\n';
    }
    return 0;
}